#region Code by Robert McLaws

//Last Updated: Robert McLaws
//Date: 22 Sept 2007

#endregion

#region Import Declarations

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using CommunityServer.Controls;
using CommunityServer.Components;
using Content = CommunityServer.Components.Content;
using System.ComponentModel;

#endregion

namespace CommunityServerStuff.Controls
{
    /// <summary>
    /// Form control implementing support for creating or editing Content.
    /// </summary>
    public class CreateEditContentForm : WrappedFormBase, IPostBackEventHandler
    {
        TextBox NameTextBox;
        TextBox TitleTextBox;
        ITextEditor BodyEditor;
        IButton SaveButton;
        IButton DeleteButton;

        #region Properties

        /// <summary>
        /// Gets or sets the save success actions.
        /// </summary>
        /// <value>The save success actions.</value>
        [
        Browsable(false),
        DefaultValue(null),
        Description("Defines the actions to take when the content is saved successfully"),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public virtual Actions SaveSuccessActions
        {
            get { return _saveSuccessActions; }
            set
            {
                if (_saveSuccessActions != null)
                    this.Controls.Remove(_saveSuccessActions);

                _saveSuccessActions = value;
                if (_saveSuccessActions != null)
                    this.Controls.Add(_saveSuccessActions);
            }
        }
        private Actions _saveSuccessActions;

        /// <summary>
        /// Gets or sets the delete success actions.
        /// </summary>
        /// <value>The delete success actions.</value>
        [
        Browsable(false),
        DefaultValue(null),
        Description("Defines the actions to take when the content is deleted successfully"),
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public virtual Actions DeleteSuccessActions
        {
            get { return _deleteSuccessActions; }
            set
            {
                if (_deleteSuccessActions != null)
                    this.Controls.Remove(_deleteSuccessActions);

                _deleteSuccessActions = value;
                if (_deleteSuccessActions != null)
                    this.Controls.Add(_deleteSuccessActions);
            }
        }
        private Actions _deleteSuccessActions;

        /// <summary>
        /// Gets or sets the content name TextBox id.
        /// </summary>
        /// <value>The content name TextBox id.</value>
        public string NameTextBoxId
        {
            get { return (string)ViewState["NameTextBoxId"] ?? string.Empty; }
            set { ViewState["NameTextBoxId"] = value; }
        }

        /// <summary>
        /// Gets or sets the title TextBox id.
        /// </summary>
        /// <value>The title TextBox id.</value>
        public string TitleTextBoxId
        {
            get { return (string)ViewState["TitleTextBoxId"] ?? string.Empty; }
            set { ViewState["TitleTextBoxId"] = value; }
        }

        /// <summary>
        /// Gets or sets the body IEditor id.
        /// </summary>
        /// <value>The body IEditor id.</value>
        public string BodyEditorId
        {
            get { return (string)ViewState["BodyEditorId"] ?? string.Empty; }
            set { ViewState["BodyEditorId"] = value; }
        }

        /// <summary>
        /// Gets or sets the save IButton id.
        /// </summary>
        /// <value>The save IButton id.</value>
        public string SaveButtonId
        {
            get { return (string)ViewState["SaveButtonId"] ?? string.Empty; }
            set { ViewState["SaveButtonId"] = value; }
        }

        /// <summary>
        /// Gets or sets the delete IButton id.
        /// </summary>
        /// <value>The delete IButton id.</value>
        public string DeleteButtonId
        {
            get { return (string)ViewState["DeleteButtonId"] ?? string.Empty; }
            set { ViewState["DeleteButtonId"] = value; }
        }

        /// <summary>
        ///  the content to edit from database, by name
        /// </summary>
        public string ContentName
        {
            get { return (string)ViewState["ContentName"] ?? string.Empty; }
            set { ViewState["ContentName"] = value; }
        }

        /// <summary>
        ///  the content to edit from database, by id
        /// </summary>
        public int ContentID
        {
            get { return (int)(ViewState["ContentID"] ?? -1); }
            set { ViewState["ContentID"] = value; }
        }

        Content _content = null;
        public override object DataSource
        {
            get
            {
                if (_content == null)
                {
                    if (ContentID > 0)
                        _content = Contents.GetContent(ContentID, true);
                    else if (!string.IsNullOrEmpty(ContentName))
                        _content = Contents.GetContent(ContentName);
                    else
                    {
                        _content = CSControlUtility.Instance().GetCurrentContent(this);
                        if (_content == null)
                            _content = new Content();
                    }
                }

                return _content;
            }
            set
            {
                if (value is Content)
                    _content = value as Content;
                else
                    throw new InvalidCastException("DataSource must be a valid Content object");
            }
        }

        public override bool Visible
        {
            get
            {
                if (!CSControlUtility.Instance().GetCurrentCSContext(this.Page).User.IsAdministrator)
                    return false;
                else
                    return base.Visible;
            }
            set
            {
                base.Visible = value;
            }
        }

        #endregion

        #region Attach Child Controls

        protected override void AttachChildControls()
        {
            NameTextBox = CSControlUtility.Instance().FindControl(this, NameTextBoxId) as TextBox;
            TitleTextBox = CSControlUtility.Instance().FindControl(this, TitleTextBoxId) as TextBox;
            BodyEditor = CSControlUtility.Instance().FindControl(this, BodyEditorId) as ITextEditor;
            SaveButton = CSControlUtility.Instance().FindButtonControl(this, SaveButtonId);
            DeleteButton = CSControlUtility.Instance().FindButtonControl(this, DeleteButtonId);

            if (BodyEditor == null || SaveButton == null)
                throw new InvalidOperationException("BodyEditorId and SaveButtonId must be valid controls to render an EditContentForm");

            SaveButton.Click += new EventHandler(SaveButton_Click);

            if (DeleteButton != null)
                DeleteButton.Click += new EventHandler(DeleteButton_Click);
        }

        protected override void AddPropertyControls()
        {
            if (this.SaveSuccessActions != null)
                this.Controls.Add(this.SaveSuccessActions);

            if (this.DeleteSuccessActions != null)
                this.Controls.Add(this.DeleteSuccessActions);

            base.AddPropertyControls();
        }

        #endregion

        #region Data Binding

        public override void DataBind()
        {
            base.DataBind();

            Content content = DataSource as Content;
            if (content == null)
            {
                this.AutomatedVisible = false;
                return;
            }

            if (!Page.IsPostBack && !content.Exists && !string.IsNullOrEmpty(Page.Request.QueryString["clientid"]))
            {
                StringBuilder script = new StringBuilder();
                script.AppendFormat("<input type=\"hidden\" name=\"{0}_ParentContent\" id=\"{0}_ParentContent\" />", this.ClientID);
                script.Append("<script type=\"text/javascript\">\n// <![CDATA[\n");
                script.Append("try { if (window.parent && window.parent.Telligent_Modal) { ");
                script.AppendFormat("var pContent = window.parent.document.getElementById('{0}'); ", JavaScript.Encode(Page.Request.QueryString["clientID"]));
                script.Append("if (pContent && pContent.innerHTML) { ");
                script.AppendFormat("document.getElementById('{0}_ParentContent').value = pContent.innerHTML;", this.ClientID);
                script.Append(Page.ClientScript.GetPostBackEventReference(this, "reloadContent"));
                script.Append("	} } } catch (e) {} \n// ]]>\n</script>");

                CSControlUtility.Instance().RegisterStartupScript(this, typeof(CreateEditContentForm), this.ClientID + "_ReloadContent", script.ToString(), false);
            }

            if (!Page.IsPostBack)
            {
                if (TitleTextBox != null)
                    TitleTextBox.Text = content.Title;

                if (NameTextBox != null)
                    NameTextBox.Text = content.Name;

                BodyEditor.Text = content.Body;
            }
        }

        #endregion

        #region Event Handlers

        void SaveButton_Click(object sender, EventArgs e)
        {
            if ((SaveButton.CausesValidation && !Page.IsValid) || !this.IsValid())
                return;

            // create/update content
            Content content = this.DataSource as Content;
            if (content == null)
                return;

            string name = content.Name;

            if (NameTextBox != null)
                name = StripBadChars(NameTextBox.Text);

            if (name.Length == 0)
                name = CSContext.Current.QueryString["contentname"];

            content = new Content(content.ID, name, TitleTextBox == null ? string.Empty : TitleTextBox.Text, BodyEditor.Text, BodyEditor.Text, DateTime.Now, content.Hidden);
            if (content.ID > 0)
                Contents.Update(content);
            else
                Contents.Add(content);

            if (this.SaveSuccessActions != null)
                this.SaveSuccessActions.Execute(this, content);
        }

        void DeleteButton_Click(object sender, EventArgs e)
        {
            if ((DeleteButton.CausesValidation && !Page.IsValid) || !this.IsValid())
                return;

            Content content = this.DataSource as Content;
            if (content != null && content.Exists)
                Contents.Delete(content);

            if (this.DeleteSuccessActions != null)
                this.DeleteSuccessActions.Execute(this, content);
        }

        #endregion

        public override bool IsValid()
        {
            if (!CSControlUtility.Instance().GetCurrentCSContext(this.Page).User.IsAdministrator)
                return false;
            else
                return base.IsValid();
        }

        #region IPostBackEventHandler Members

        public void RaisePostBackEvent(string eventArgument)
        {
            if (eventArgument == "reloadContent")
            {
                EnsureChildControls();

                BodyEditor.Text = Page.Request.Form[this.ClientID + "_ParentContent"];
            }
        }

        #endregion

        /// <summary>
        /// remove illegal chars from content name
        /// </summary>
        /// <param name="sName"></param>
        /// <returns></returns>
        public static string StripBadChars(string name)
        {
            // remove bad characters
            for (int i = 0; i < name.Length; i++)
                if ((!Char.IsLetterOrDigit(name[i])) | (!name[i].Equals("-")) | (!name[i].Equals("_")))
                {
                    name = name.Remove(i, 1);
                    i--;
                }

            return name;
        }
    }
}
